package cn.elead.it.sso.system.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.gitee.elead.mybatisplus.service.BaseServiceImpl;

import cn.elead.it.sso.system.dao.IDeptDao;
import cn.elead.it.sso.system.model.Dept;
import cn.elead.it.sso.system.model.User;
import cn.elead.it.sso.system.model.query.DeptQuery;
import cn.elead.it.sso.system.service.IDeptService;
import cn.elead.it.sso.system.service.IUserService;
import cn.elead.it.sso.system.service.dto.DeptDTO;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

/**
 * <p>
 * 部门信息服务类
 * </p>
 *
 * @author luopeng
 */
@Service
public class DeptService extends BaseServiceImpl<IDeptDao, Dept> implements IDeptService {

	@Autowired
	private IUserService userService;

	private List<Dept> queryList(DeptQuery query) {
		return query().like(StrUtil.isNotBlank(query.getName()), Dept::getName, query.getName())
				//.eq(ObjectUtil.isNotNull(query.getEnabled()), Dept::getStatus, query.getEnabled() ? 1 : 0)
				.eq(StrUtil.isNotBlank(query.getPid()), Dept::getPid, query.getPid())
				.between(ObjectUtil.isNotNull(query.getStartTime()), Dept::getCreatedTime, query.getStartTime(),
						query.getEndTime()) // 今天
				.list();
	}

	private List<Dept> queryByPids(List<Dept> ids) {
		List<Dept> list = new ArrayList<Dept>();
		for (Dept dept : ids) {
			List<Dept> depts = queryByPid(dept.getId());
			if (CollectionUtil.isNotEmpty(depts)) {
				list.addAll(queryByPids(depts));
			}
			list.addAll(depts);
		}
		return list;
	}
	
	public List<Dept> queryByPid(String id) {
		return query().eq(Dept::getPid, id).list();
	}

	@Override
	@Cacheable(value = "dept" ,key = "#p0.name")
	public List<DeptDTO> list(DeptQuery query) {
		List<Dept> list = queryList(query);
		int count = query().count().intValue();
		List<String> searchId = new ArrayList<>();
		if (list.size() != count) {
			for (Dept dept : list) {
				searchId.add(dept.getPid());
			}
			list.addAll(queryByPids(list));
		} else {
			searchId.add("0");
		}
		// 节点列表（散列表，用于临时存储节点对象）
		Map<String, DeptDTO> treeNodes = new HashMap<String, DeptDTO>();
		// 根据结果集构造节点列表（存入散列表）
		for (Dept dept : list) {
			treeNodes.put(dept.getId(), dept.convert(DeptDTO.class));
		}
		// 构造无序的多叉树
		Set<Entry<String, DeptDTO>> treeEntrySet = treeNodes.entrySet();
		for (Entry<String, DeptDTO> treeEntry : treeEntrySet) {
			DeptDTO node = treeEntry.getValue();
			String pid = node.getPid();
			if (StrUtil.isNotBlank(pid) && !StrUtil.equals(pid, "0")) {
				DeptDTO deptDTO = treeNodes.get(pid);
				if (ObjectUtil.isNull(deptDTO)) {
					continue;
				}
				Integer status = deptDTO.getStatus();
				deptDTO.setEnabled(status == 1 ? true : false);
				deptDTO.getChildren().add(node);
			}
		}
		// 过滤出Pid为0
		return treeNodes.entrySet().stream().map(Entry::getValue).filter(node -> {
			if (searchId.contains(node.getPid())) {
				return true;
			} else {
				return false;
			}
		}).collect(Collectors.toList());

	}

	@Override
	@Transactional
	public void init() {

		Map<String, String> deptMap = new HashMap<>();

		List<User> users = userService.list();
		for (User user : users) {
			String department = user.getDepartment();
			List<String> departments = Arrays.asList(department.split("-->"));
			String pid = "0";
			Dept entity = null;
			for (String deptName : departments) {
				String id = deptMap.get(deptName);
				if (StrUtil.isNotBlank(id)) {
					pid = id;
					continue;
				}
				Dept dept = query().eq(Dept::getName, deptName).getOne();
				if (ObjectUtil.isNull(dept)) {
					entity = new Dept();
					entity.setName(deptName);
					entity.setStatus(1);
					entity.setPid(pid);
					pid = IdUtil.simpleUUID();
					entity.setId(pid);
					save(entity);
				} else {
					pid = dept.getId();
				}
				deptMap.put(deptName, pid);
			}
		}
	}

}
